package com.woniuxy.courseservice.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.core.model.Result;
import com.woniuxy.core.status.CoachState;
import com.woniuxy.core.status.CourseState;
import com.woniuxy.core.status.ProductState;
import com.woniuxy.core.util.MyJwtUtil;
import com.woniuxy.core.util.PageInfo;
import com.woniuxy.courseclient.client.CoachFeignClient;
import com.woniuxy.courseclient.client.ProductFeignClient;
import com.woniuxy.courseclient.client.dto.CoachLoginDto;
import com.woniuxy.courseclient.client.dto.CourseProductDto;
import com.woniuxy.coursedao.mapper.OrdinaryCourseMapper;
import com.woniuxy.coursedao.model.OrdinaryCourse;
import com.woniuxy.coursedao.model.TeamCourse;
import com.woniuxy.coursemodel.dto.PageDto;
import com.woniuxy.coursemodel.param.DayCourseParam;
import com.woniuxy.coursemodel.param.OneCourseParam;
import com.woniuxy.coursemodel.param.OrdinaryCoursePageParam;
import com.woniuxy.coursemodel.param.WeekCourseParam;
import com.woniuxy.courseservice.service.OrdinaryCourseService;
import com.woniuxy.courseservice.service.exception.OrdinaryCourseException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 冉杰
 * @since 2024-01-15
 */
@Service
public class OrdinaryCourseServiceImpl extends ServiceImpl<OrdinaryCourseMapper, OrdinaryCourse> implements OrdinaryCourseService {

    @Resource
    private CoachFeignClient coachFeignClient;
    @Resource
    private ProductFeignClient productFeignClient;
    @Override
    public void one(OneCourseParam param) {
        Result<CourseProductDto> result = productFeignClient.findById(param.getCourseProductId());
        if (!result.getFlag()) throw new OrdinaryCourseException(result.getCode(), result.getMsg());
        if (BeanUtil.isEmpty(result.getData())) throw new OrdinaryCourseException(6008,"该普通课程产品不存在");
        CourseProductDto productDto = result.getData();
        if (productDto.getCourseProductState().intValue()== ProductState.IS_DISABLED.getState().intValue())
            throw new OrdinaryCourseException(6001,"该普通课程产品不可用");
        LambdaQueryWrapper<OrdinaryCourse> wrapper = new LambdaQueryWrapper<>();
        wrapper.between(OrdinaryCourse::getCourseStartDate, param.getCourseStartDate(), param.getCourseEndDate());
        long count = count(wrapper);
        if (count!=0) throw new OrdinaryCourseException
                (4020,param.getCourseStartDate()+"至"+param.getCourseEndDate()+"已有普通课程排课");
//        Result<CoachLoginDto> result1 = coachFeignClient.searchCoachByCoachId(productDto.getCoachId());
//        if (!result1.getFlag()) throw new OrdinaryCourseException(result1.getCode(), result1.getMsg());
//        CoachLoginDto coachLoginDto = result1.getData();
//        if (coachLoginDto.getAuthState().intValue()== CoachState.IS_NOT_AUTH.getState().intValue())
//            throw new OrdinaryCourseException(6002,"该课程")
        OrdinaryCourse ordinaryCourse = BeanUtil.toBean(param, OrdinaryCourse.class);
        ordinaryCourse.setCoachId(productDto.getCoachId());
        ordinaryCourse.setCourseDuration(2);
        ordinaryCourse.setCourseState(CourseState.IS_ENABLE.getState());
        ordinaryCourse.setCourseProductId(param.getCourseProductId());
        ordinaryCourse.setVenueId(productDto.getVenueId());
        save(ordinaryCourse);
    }


    @Override
    public void del(Integer ordinaryCourseId) {
        removeById(ordinaryCourseId);
    }

    @Override
    @Transactional
    public void day(DayCourseParam param) {
        List<Integer> courseProductIds = param.getCourseProductIds();
        if (courseProductIds.size()!=4) throw new OrdinaryCourseException(6012,"请选择四个课程");
        ArrayList<CourseProductDto> list = new ArrayList<>();
        for (Integer courseProductId : courseProductIds) {
            Result<CourseProductDto> result = productFeignClient.findById(courseProductId);
            if (!result.getFlag()) throw new OrdinaryCourseException(result.getCode(), result.getMsg());
            if (BeanUtil.isEmpty(result.getData())) throw new OrdinaryCourseException(6008,"部分普通课程产品不存在");
            CourseProductDto productDto = result.getData();
            if (productDto.getCourseProductState().intValue()== ProductState.IS_DISABLED.getState().intValue())
                throw new OrdinaryCourseException(6002,productDto.getCourseProductName()+"课程产品不可用");
            list.add(productDto);
        }
        ArrayList<OrdinaryCourse> courseList = arrange(param.getDay(), list);
        saveBatch(courseList);
    }

    @Override
    @Transactional
    public void week(WeekCourseParam param) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate dateTime1 = LocalDate.parse(param.getStartDay(), formatter);
        LocalDate dateTime2 = LocalDate.parse(param.getEndDay(), formatter);
        long days = ChronoUnit.DAYS.between(dateTime1, dateTime2);
        if (days != 7) throw new OrdinaryCourseException(6013,"请选择一周七天的时间进行排课");
        Result<List<CourseProductDto>> result = productFeignClient.findByVenueId(param.getVenueId());
        if (!result.getFlag()) throw new OrdinaryCourseException(result.getCode(), result.getMsg());
        if (BeanUtil.isEmpty(result.getData())) throw new OrdinaryCourseException(6008,"该普通课程产品不存在");
        List<CourseProductDto> dtos = result.getData();
        ArrayList<Integer> list = new ArrayList<>();
        for (CourseProductDto dto : dtos) {
            Integer courseProductId = dto.getCourseProductId();
            list.add(courseProductId);
        }
        // 将字符串转换为 Date 对象
        Date date = DateUtil.parse(param.getStartDay()).toJdkDate();
        // 将 Date 对象转换为 LocalDate 对象
        LocalDate localDate = date.toInstant().atZone(java.time.ZoneId.systemDefault()).toLocalDate();
        for (int i = 0; i < 7; i++) {
            ArrayList<CourseProductDto> listDtos = new ArrayList<>();
            Random rand = new Random();
            for (int j = 0; j < dtos.size(); j++) {
                int randomIndex = rand.nextInt(dtos.size());
                CourseProductDto randomElement = dtos.get(randomIndex);
                listDtos.add(randomElement);
            }
            ArrayList<OrdinaryCourse> arrange = arrange(localDate.plusDays(i).toString(), listDtos);
            saveBatch(arrange);
        }
    }

    @Override
    public PageInfo<PageDto> byPage(OrdinaryCoursePageParam param) {
        LambdaQueryWrapper<OrdinaryCourse> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrdinaryCourse::getVenueId,param.getVenueId()).ge(OrdinaryCourse::getCourseStartDate, LocalDate.now())
                .orderByDesc(OrdinaryCourse::getCourseStartDate);
        Page<OrdinaryCourse> page = new Page<>(param.getPageNum(), param.getPageSize());
        page(page,wrapper);
        List<OrdinaryCourse> records = page.getRecords();
        ArrayList<PageDto> list = new ArrayList<>();
        for (OrdinaryCourse record : records) {
            PageDto dto = BeanUtil.toBean(record, PageDto.class);
            Result<CoachLoginDto> result = coachFeignClient.searchCoachByCoachId(record.getCoachId());
            if (!result.getFlag()) throw new OrdinaryCourseException(result.getCode(), result.getMsg());
            dto.setCoachName(result.getData().getCoachName());
            Result<CourseProductDto> result1 = productFeignClient.findById(record.getCourseProductId());
            if (!result1.getFlag()) throw new OrdinaryCourseException(result1.getCode(), result1.getMsg());
            dto.setCourseProductName(result1.getData().getCourseProductName());
            list.add(dto);
        }
        PageInfo<PageDto> pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setPages(page.getPages());
        pageInfo.setList(list);
        return pageInfo;
    }

    @Override
    @Transactional
    public void delByIds(List<Integer> ordinaryCourseIds, Integer venueId) {
        List<OrdinaryCourse> ordinaryCourses = listByIds(ordinaryCourseIds);
        for (OrdinaryCourse ordinaryCourse : ordinaryCourses) {
            if (ordinaryCourse.getVenueId().intValue()!=venueId.intValue())
                throw new OrdinaryCourseException(6055,"部分普通课程不属于当前场馆不能删除");
        }
        removeByIds(ordinaryCourses);
    }

    public ArrayList<OrdinaryCourse> arrange(String day,ArrayList<CourseProductDto> list){
        ArrayList<OrdinaryCourse> courseList = new ArrayList<>();
        OrdinaryCourse first = new OrdinaryCourse();
        first.setCourseStartDate(day+" "+"10:00:00");
        first.setCourseEndDate(day+" "+"12:00:00");
        first.setCourseDuration(2);
        first.setCourseState(CourseState.IS_ENABLE.getState());
        first.setCoachId(list.get(0).getCoachId());
        first.setCourseProductId(list.get(0).getCourseProductId());
        first.setVenueId(list.get(0).getVenueId());
        courseList.add(first);
        OrdinaryCourse second = new OrdinaryCourse();
        second.setCourseStartDate(day+" "+"14:00:00");
        second.setCourseEndDate(day+" "+"16:00:00");
        second.setCourseDuration(2);
        second.setCourseState(CourseState.IS_ENABLE.getState());
        second.setCoachId(list.get(1).getCoachId());
        second.setCourseProductId(list.get(1).getCourseProductId());
        second.setVenueId(list.get(0).getVenueId());
        courseList.add(second);
        OrdinaryCourse third = new OrdinaryCourse();
        third.setCourseStartDate(day+" "+"16:00:00");
        third.setCourseEndDate(day+" "+"18:00:00");
        third.setCourseDuration(2);
        third.setCourseState(CourseState.IS_ENABLE.getState());
        third.setCoachId(list.get(2).getCoachId());
        third.setCourseProductId(list.get(2).getCourseProductId());
        third.setVenueId(list.get(0).getVenueId());
        courseList.add(third);
        OrdinaryCourse fourth = new OrdinaryCourse();
        fourth.setCourseStartDate(day+" "+"20:00:00");
        fourth.setCourseEndDate(day+" "+"22:00:00");
        fourth.setCourseDuration(2);
        fourth.setCourseState(CourseState.IS_ENABLE.getState());
        fourth.setCoachId(list.get(3).getCoachId());
        fourth.setCourseProductId(list.get(3).getCourseProductId());
        fourth.setVenueId(list.get(0).getVenueId());
        courseList.add(fourth);
        LocalDateTime startTime = LocalDateTime.parse(day + "T00:00:00");
        LocalDateTime endTime = LocalDateTime.parse(day + "T23:59:59");
        LambdaQueryWrapper<OrdinaryCourse> wrapper = new LambdaQueryWrapper<>();
        wrapper.between(OrdinaryCourse::getCourseStartDate, startTime, endTime);
        long count = count(wrapper);
        if (count!=0) throw new OrdinaryCourseException(4020,day+"已有普通课程排课");
        return courseList;
    }
}
